package com.zfast.forge.qlExpress;

import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
import com.zfast.forge.annotation.Operator;
import lombok.SneakyThrows;

import java.lang.reflect.Method;

/**
 * QLExpress优化工具
 *
 * @author zgn
 * @Description: QLExpressUtil
 * @date 2024/2/29 0029
 */
public class QLExpressUtil {


    /**
     * 通过FormulaEnum中的运算符自动添加映射方法
     *
     * @param runner QL解析器
     * @param enumValue 公式
     * @author zgn
     * @date 2024/2/29 0029
     */
    @SneakyThrows
    public static void autoFunctionsBind(ExpressRunner runner, FormulaEnum enumValue) {
        //公式中需要的运算符
        String[] functions = enumValue.getFunctions();
        //方法集所在类
        Class<BadFunctions> badFunctionsClass = BadFunctions.class;
        //方法集
        Method[] methods = badFunctionsClass.getMethods();

        for (int i = 0; i < methods.length; i++) {
            Method method = methods[i];
            Operator annotation = method.getAnnotation(Operator.class);

            if (null != annotation) {
                String value = annotation.value();

                for (int j = 0; j < functions.length; j++) {
                    String function = functions[j];

                    if (function.equals(value)) {
                        String name = method.getName();
                        Class<?>[] parameterTypes = method.getParameterTypes();

                        runner.addFunctionOfClassMethod(annotation.value(), badFunctionsClass.getName(), name, parameterTypes, null);
                    }
                }
            }


        }
    }

    /**
     * 通用公式处理
     *
     * @author zgn
     * @date 2024/2/29 0029
     * @param    enumValue 公式
     * @param    params 参数
     * @param    runner QL解析器
     * @return java.lang.Object
     */
    @SneakyThrows
    public static Object execute(FormulaEnum enumValue, DefaultContext<String, Object> params, ExpressRunner runner) {
        String express = enumValue.getValue();

        /*if (null!=enumValue.getFunctions()) {
            autoFunctionsBind(runner, enumValue);
        }*/

        return runner.execute(express, params, null, true, false);
    }
}
